
const waitImgLoaded = async (root) => {
  const imgs = root instanceof HTMLImageElement ? [root] : [...root.querySelectorAll('img')];
  return await Promise.all(imgs.map(img => (
    new Promise(resolve => {
      img.addEventListener('load', () => resolve(img))
      img.addEventListener('error', () => resolve(img))
    })
  )))
}

const mdIFrame = (function () {
  /** @type {HTMLIFrameElement} */
  const $frame = document.querySelector('#passage-content');
  const frameWindow = $frame.contentWindow

  function resizeIFrame() {
    const height = frameWindow.document.documentElement.scrollHeight + 10;
    $frame.style.height = height + 'px';
  }

  async function putHTML(html) {
    frameWindow.document.querySelector('html').innerHTML = html;
    frameWindow.document.querySelector('html').innerHTML += `<style>.CodeMirror-scroll {height: auto !important;}</style>`;

    await waitImgLoaded(frameWindow.document);

    // hook resize
    resizeIFrame();
    window.addEventListener('resize', resizeIFrame);

    frameWindow.scrollToAnchor = scrollToAnchor
    frameWindow.jumpToOtherPage = jumpToOtherPage
    // intercept <a> Click

    const $aArr = frameWindow.document.querySelectorAll("a[href]");

    $aArr.forEach(function ($a) {
      const href = $a.getAttribute('href');
      if (/^#.*$/.test(href)) {
        $a.href = `javascript:scrollToAnchor(\`${href.slice(1)}\`)`
      } else {
        $a.href = `javascript:jumpToOtherPage(\`${href}\`)`
      }
    })

  }

  const headerHeight = document.querySelector('#nav-container').clientHeight

  function scrollToAnchor(anchorName) {
    const $a = frameWindow.document.querySelector(`a[name=${anchorName}]`)
    console.log($a.parentElement)
    window.scrollTo(0, $a.parentElement.offsetTop + headerHeight)
  }

  function jumpToOtherPage(pageHref) {
    location.href = pageHref
  }

  var $lastAnchor;
  function watchScroll(callback) {
    const $anchors = frameWindow.document.querySelectorAll("a[name]");
    let lastCallTime = new Date().getTime();
    const throttlingTime = 100;
    window.addEventListener("scroll", () => {
      const cur = new Date().getTime();
      if (cur - lastCallTime < throttlingTime) return;
      const parentScrollTop = document.querySelector("html").scrollTop
      if (parentScrollTop < $anchors[0].offsetTop + headerHeight) {
        if ($lastAnchor !== $anchors[0]) {
          callback($anchors[0])
        }
      }

      for (let i = 0; i < $anchors.length - 1; i++) {
        const first = $anchors[i];
        const second = $anchors[i + 1];

        if (first.parentElement.offsetTop + headerHeight < parentScrollTop &&
          second.parentElement.offsetTop + headerHeight > parentScrollTop) {
          if ($lastAnchor !== first) {
            callback(first);
            $lastAnchor = first
          }
          break;
        }
      }

      lastCallTime = cur
    })
  }

  return {
    putHTML: putHTML,
    scrollToAnchor: scrollToAnchor,
    watchScroll: watchScroll,
    window: frameWindow
  }
})()